package cn.snmp.mutual.uk.beans;

import java.io.*;

import cn.snmp.mutual.uk.pdu.DiscoveryPdu;
import cn.snmp.mutual.uk.stack.*;

public class UsmDiscoveryBean {
    private static final String version_id = "@(#)$Id: UsmDiscoveryBean.java,v 1.21 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd";
    private SnmpContextv3Pool context;
    private String userName;
    private String userAuthPassword;
    private String userPrivPassword;
    private int authProtocol;
    private int privProtocol;
    private int[] retry_intervals;

    public UsmDiscoveryBean(final String host, final int port) throws IOException {
        this(host, port, null, "Standard");
    }

    public UsmDiscoveryBean(final String host, final int port, final String bindAddr, final String typeSocketA) throws IOException {
        this.userName = null;
        this.userAuthPassword = null;
        this.userPrivPassword = null;
        this.retry_intervals = new int[]{500, 1000, 2000, 5000, 5000};
        this.context = new SnmpContextv3Pool(host, port, bindAddr, typeSocketA);
    }

    public void setAuthenticationDetails(final String newUserName, final String newUserPassword, final int protocol) {
        this.userName = newUserName;
        this.userAuthPassword = newUserPassword;
        this.authProtocol = protocol;
    }

    public void setPrivacyDetails(final String newUserPassword, final int protocol) {
        this.userPrivPassword = newUserPassword;
        this.privProtocol = protocol;
    }

    public void setRetryIntervals(final int[] rinterval) {
        this.retry_intervals = rinterval;
    }

    public void startDiscovery() throws PduException, IOException {
        try {
            this.discoveryEngineId();
        } catch (PduException exc) {
            this.freeResources();
            throw new PduException("Engine ID discovery: " + exc.getMessage());
        }
        try {
            this.discoveryTimeLine();
        } catch (PduException exc) {
            final TimeWindow tWindow = TimeWindow.getCurrent();
            final String engineId = tWindow.getSnmpEngineId(this.context.getSendToHostAddress(), this.context.getPort());
            if (!tWindow.isTimeLineKnown(engineId)) {
                this.freeResources();
                throw new PduException("Timeline discovery: " + exc.getMessage());
            }
        }
        if (AsnObject.debug > 4) {
            System.out.println(this.getClass().getName() + ".startDiscovery(): " + "Done, context " + this.context.toString());
        }
        this.freeResources();
    }

    public void freeResources() {
        this.context.destroy();
        this.context = null;
    }

    protected void discoveryEngineId() throws PduException, IOException {
        final TimeWindow tWindow = TimeWindow.getCurrent();
        final String engineId = tWindow.getSnmpEngineId(this.context.getHost(), this.context.getPort());
        if (engineId == null) {
            if (AsnObject.debug > 4) {
                System.out.println(this.getClass().getName() + ".discoveryEngineId(): " + "Starting discovery Engine ID ...");
            }
            this.context.setUserName("");
            this.context.setUseAuthentication(false);
            this.context.setUsePrivacy(false);
            this.context.setContextEngineId(new byte[0]);
            this.context.setContextName("");
            final DiscoveryPdu pdu = new DiscoveryPdu(this.context);
            pdu.setRetryIntervals(this.retry_intervals);
            pdu.send();
            pdu.waitForSelf();
            final Varbind[] vars = pdu.getResponseVarbinds();
        }
    }

    protected void discoveryTimeLine() throws PduException, IOException {
        final TimeWindow tWindow = TimeWindow.getCurrent();
        final String engineId = tWindow.getSnmpEngineId(this.context.getSendToHostAddress(), this.context.getPort());
        if (!tWindow.isTimeLineKnown(engineId) && this.userName != null) {
            if (AsnObject.debug > 4) {
                System.out.println(this.getClass().getName() + ".discoveryTimeLine(): " + "Starting discovery Timeline ...");
            }
            this.context.setUserName(this.userName);
            this.context.setUserAuthenticationPassword(this.userAuthPassword);
            this.context.setUseAuthentication(true);
            this.context.setAuthenticationProtocol(this.authProtocol);
            this.context.setContextEngineId(new byte[0]);
            this.context.setContextName("");
            if (this.userPrivPassword != null) {
                this.context.setUsePrivacy(true);
                this.context.setUserPrivacyPassword(this.userPrivPassword);
                this.context.setPrivacyProtocol(this.privProtocol);
            } else {
                this.context.setUsePrivacy(false);
            }
            final DiscoveryPdu pdu = new DiscoveryPdu(this.context);
            pdu.setRetryIntervals(this.retry_intervals);
            pdu.send();
            pdu.waitForSelf();
            final Varbind[] vars = pdu.getResponseVarbinds();
            if (AsnObject.debug > 4) {
                System.out.println("Did discovery time line");
            }
        }
    }
}
